package co.edu.unal.geditor.view;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.util.ArrayList;

import co.edu.unal.geditor.controller.App;
import co.edu.unal.geditor.model.BoundBox;
import co.edu.unal.geditor.view.controlpoints.ControlPoint;
import co.edu.unal.geditor.view.controlpoints.DownControlPoint;
import co.edu.unal.geditor.view.controlpoints.LeftControlPoint;
import co.edu.unal.geditor.view.controlpoints.LeftDownControlPoint;
import co.edu.unal.geditor.view.controlpoints.LeftUpControlPoint;
import co.edu.unal.geditor.view.controlpoints.RightControlPoint;
import co.edu.unal.geditor.view.controlpoints.RightDownControlPoint;
import co.edu.unal.geditor.view.controlpoints.RightUpControlPoint;
import co.edu.unal.geditor.view.controlpoints.UpControlPoint;
import co.edu.unal.geditor.view.tools.Tool;

public class BoundBoxView {

	public BoundBoxView(BoundBox Owner) {
		m_owner = Owner;
		chageCpPoints();
		registerControlPoints();
		
	}
	protected void registerControlPoints(){
		m_lControlPoints.add(m_cpLU);
		m_lControlPoints.add(m_cpL);
		m_lControlPoints.add(m_cpLD);
		m_lControlPoints.add(m_cpD);
		m_lControlPoints.add(m_cpRD);
		m_lControlPoints.add(m_cpR);
		m_lControlPoints.add(m_cpRU);
		m_lControlPoints.add(m_cpU);
	}

	public void paint(Graphics g) {

		m_owner.createOtherPoints();
		chageCpPoints();
		Point ul = m_owner.getLeftUp();
		Point bd = m_owner.getRightDown();

		// casting (!) because of a Java design error ...
		Graphics2D gg = (Graphics2D) g;

		gg.setColor(DEF_SELECTED_COLOR);

		// 1. save active stroke
		Stroke stroke = gg.getStroke();

		// 2. change active stroke to dashed
		gg.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_SQUARE,
						BasicStroke.JOIN_MITER, 10.0f, DEF_DASHED_PATTERN,
						DEF_DASHED_));
		gg.drawRect(ul.x, ul.y, bd.x - ul.x + 1, bd.y - ul.y + 1);

		// 3. recover active stroke
		gg.setStroke(stroke);
		// App.getInstance().getCanvas().update();
		for (ControlPoint cp : m_lControlPoints) {
			cp.paint(gg);
		}
	}

	public void chageCpPoints() {
		m_cpLU.changePoint(m_owner.getLeftUp());
		m_cpL.changePoint(new Point(m_owner.getLeftUp().x,
				(m_owner.getLeftUp().y + (m_owner.getHeight() / 2))));
		m_cpLD.changePoint(m_owner.getLeftDown());
		m_cpD.changePoint(new Point((m_owner.getLeftDown().x + (m_owner
				.getWidth() / 2)), m_owner.getRightDown().y));
		m_cpRD.changePoint(m_owner.getRightDown());
		m_cpR.changePoint(new Point(m_owner.getRightDown().x, (m_owner
				.getRightUp().y + (m_owner.getHeight() / 2))));
		m_cpRU.changePoint(m_owner.getRightUp());
		m_cpU.changePoint(new Point((m_owner.getLeftUp().x + (m_owner
				.getWidth() / 2)), m_owner.getLeftUp().y));
	}

	public boolean contain(Point ptContained) {
		if (m_owner.getLeftUp().x < ptContained.x
				&& m_owner.getLeftUp().y < ptContained.y
				&& m_owner.getRightDown().x > ptContained.x
				&& m_owner.getRightDown().y > ptContained.y
				&& m_owner.isSelected()) {
			App.getInstance().getCanvas().getActiveTool().setActiveAction(
					Tool.MOVE);
			App.getInstance().getCanvas().setCursor(
					new Cursor(Cursor.MOVE_CURSOR));
			return true;
		}
		return false;
	}

	public boolean containControlPoints(Point ptContained) {
		boolean retorno = false;
		for (ControlPoint cp : m_lControlPoints) {
			if (cp.contain(ptContained) && m_owner.isSelected()) {
				App.getInstance().getCanvas().getActiveTool().setActiveAction(
						Tool.RESIZE);
				cp.changeCursor();
				activeControlPoint = cp;
				retorno = true;
				break;
			}
		}
		return (retorno);
	}

	public boolean containedIn(BoundBox bb) {
		return (m_owner.getLeftUp().x > bb.getLeftUp().x
				&& m_owner.getLeftUp().y > bb.getLeftUp().y
				&& m_owner.getRightDown().x < bb.getRightDown().x && m_owner
				.getRightDown().y < bb.getRightDown().y);
	}

	public void moved(int x, int y) {
		m_owner.setLeftUp(new Point(m_owner.getLeftUp().x + x, m_owner
				.getLeftUp().y
				+ y));
		m_owner.setRightDown(new Point(m_owner.getRightDown().x + x, m_owner
				.getRightDown().y
				+ y));
	}

	public void resizing(Point cursorPosition) {
		activeControlPoint.resizing(cursorPosition, m_owner);
	}
	public boolean isLine() {
		return isLine;
	}

	protected BoundBox m_owner;
	protected ArrayList<ControlPoint> m_lControlPoints = new ArrayList<ControlPoint>();

	public static final Color DEF_SELECTED_COLOR = Color.LIGHT_GRAY;
	public static final float[] DEF_DASHED_PATTERN = new float[] { 0.5f, 0.5f };
	public static final float DEF_DASHED_ = 1.0f;

	protected ControlPoint m_cpLU = new LeftUpControlPoint();
	private ControlPoint m_cpL = new LeftControlPoint();
	private ControlPoint m_cpLD = new LeftDownControlPoint();
	private ControlPoint m_cpD = new DownControlPoint();
	protected ControlPoint m_cpRD = new RightDownControlPoint();
	private ControlPoint m_cpR = new RightControlPoint();
	private ControlPoint m_cpRU = new RightUpControlPoint();
	private ControlPoint m_cpU = new UpControlPoint();
	protected ControlPoint activeControlPoint;
	
	protected boolean  isLine=false;
	// TODO : Calcular la dimensión de los controlPoints y mandarla como
	// parámetro al constructor

	

}
